package com.iflytek.jzcpx.procuracy.ocr.common.mybatis;

import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Date;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);

    private static final String CREATE_TIME_FIELD = "createTime";
    private static final String UPDATE_TIME_FIELD = "updateTime";

    @Override
    public void insertFill(MetaObject metaObject) {
        Class<?> createTimeType = metaObject.getSetterType(CREATE_TIME_FIELD);
        Class<?> updateTimeType = metaObject.getSetterType(UPDATE_TIME_FIELD);
        Object createTime = this.getFieldValByName(CREATE_TIME_FIELD, metaObject);
        Object updateTime = this.getFieldValByName(UPDATE_TIME_FIELD, metaObject);

        if (LocalDateTime.class.equals(createTimeType)) {
            LocalDateTime now = LocalDateTime.now();
            if (createTime == null) {
                this.strictInsertFill(metaObject, CREATE_TIME_FIELD, LocalDateTime.class, now);
            }

            filleUpdateTime(metaObject, updateTimeType, updateTime, LocalDateTimeUtil.toEpochMilli(now));
        }
        else if (Instant.class.equals(createTimeType)) {
            Instant now = Instant.now();
            if (createTime == null) {
                this.strictInsertFill(metaObject, CREATE_TIME_FIELD, Instant.class, now);
            }

            filleUpdateTime(metaObject, updateTimeType, updateTime, LocalDateTimeUtil.toEpochMilli(now));
        }
        else if (Date.class.equals(createTimeType)) {
            Date now = new Date();
            if (createTime == null) {
                this.strictInsertFill(metaObject, CREATE_TIME_FIELD, Date.class, now);
            }

            filleUpdateTime(metaObject, updateTimeType, updateTime, now.getTime());
        }
    }

    private void filleUpdateTime(MetaObject metaObject, Class<?> fieldType, Object fieldValue, long timestamp) {
        if (fieldValue == null) {
            if (LocalDateTime.class.equals(fieldType)) {
                this.strictInsertFill(metaObject, UPDATE_TIME_FIELD, LocalDateTime.class,
                                      LocalDateTimeUtil.of(timestamp));
            }
            else if (Instant.class.equals(fieldType)) {
                this.strictInsertFill(metaObject, UPDATE_TIME_FIELD, Instant.class, Instant.ofEpochMilli(timestamp));
            }
            else if (Date.class.equals(fieldType)) {
                this.strictInsertFill(metaObject, UPDATE_TIME_FIELD, Date.class, new Date(timestamp));
            }
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        Class<?> fieldType = metaObject.getSetterType(UPDATE_TIME_FIELD);
        Object updateTime = this.getFieldValByName(UPDATE_TIME_FIELD, metaObject);
        if (updateTime == null) {
            if (LocalDateTime.class.equals(fieldType)) {
                this.strictUpdateFill(metaObject, UPDATE_TIME_FIELD, LocalDateTime.class, LocalDateTime.now());
            }
            else if (Instant.class.equals(fieldType)) {
                this.strictUpdateFill(metaObject, UPDATE_TIME_FIELD, Instant.class, Instant.now());
            }
            else if (Date.class.equals(fieldType)) {
                this.strictUpdateFill(metaObject, UPDATE_TIME_FIELD, Date.class, new Date());
            }
        }
    }

}
